package com.b2b2000.jira.plugin.projectpanel.fragments;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import com.atlassian.jira.ComponentManager;
import com.atlassian.jira.config.properties.ApplicationProperties;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.issuetype.IssueType;
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.issue.search.SearchResults;
import com.atlassian.jira.jql.builder.JqlClauseBuilder;
import com.atlassian.jira.jql.builder.JqlQueryBuilder;
import com.atlassian.jira.plugin.projectpanel.fragment.ProjectTabPanelFragment;
import com.atlassian.jira.plugin.projectpanel.fragment.impl.AbstractFragment;
import com.atlassian.jira.project.browse.BrowseContext;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.query.Query;
import com.atlassian.velocity.VelocityManager;

/**
 * @author jaime A HTML {@link #Abstracfragment} to be displayed in a
 *         {@link #FragmentBasedProjectPanel}, that lists a definible amount of
 *         issues (property {@link #MAX_ISSUES_LIMIT}) of the type passed
 *         {@link #listedIssueType}.
 *
 */
public class ProjectListIssuesFragmentImpl extends AbstractFragment implements ProjectTabPanelFragment {

	private static final String TEMPLATE_DIRECTORY_PATH = "templates/fragments/";
	private static final String MAX_ISSUES_LIMIT = new String("20");
	protected String listedIssueType;
	private Boolean showFragment = true;
	private final SearchProvider searchProvider;

	public ProjectListIssuesFragmentImpl(VelocityManager velocityManager, ApplicationProperties applicationProperties,
			JiraAuthenticationContext jiraAuthenticationContext, SearchProvider searchProvider) {
		super(velocityManager, applicationProperties, jiraAuthenticationContext);
		this.searchProvider = searchProvider;
	}

	public String getListedIssueType() {
		return listedIssueType;
	}

	public void setListedIssueType(String listedIssueType) {
		this.listedIssueType = listedIssueType;
	}

	public String getId() {
		// TODO: generalize this for every type of issue so the format can be
		// different for each one of them.
		return "project-list-issues";
	}

	protected String getTemplateDirectoryPath() {
		return TEMPLATE_DIRECTORY_PATH;
	}

	public boolean showFragment(BrowseContext ctx) {
		return showFragment;
	}

	@Override
	protected Map<String, Object> createVelocityParams(BrowseContext browseContext) {
		Map<String, Object> velocityParams = super.createVelocityParams(browseContext);
		IssueType foundIssueType = null;
		foundIssueType = findIssueTypeByName();
		velocityParams.put("maxIssuesLimit", MAX_ISSUES_LIMIT);
		velocityParams.put("fragmentId", getTemplateDirectoryPath());
		velocityParams.put("projectId", browseContext.getProject().getId());

		SearchResults results = null;
		if (foundIssueType != null) {
			results = getIssues(browseContext, foundIssueType.getId());
			velocityParams.put("issueTypeName", foundIssueType.getName());
			velocityParams.put("issues", results.getIssues());
			velocityParams.put("issuesCount", Integer.valueOf(results == null ? 0 : results.getTotal()));
		} else {
			showFragment = false;
		}
		return velocityParams;
	}

	protected IssueType findIssueTypeByName() {
		Collection<IssueType> issueTypes = ComponentManager.getInstance().getConstantsManager().getAllIssueTypeObjects();
		Iterator<IssueType> issueTypeIterator = issueTypes.iterator();
		IssueType issueTypeRequisite = null;
		while (issueTypeIterator.hasNext()) {
			IssueType issueType = (IssueType) issueTypeIterator.next();
			if (issueType.getNameTranslation("es_ES").toLowerCase().equals(listedIssueType.toLowerCase())) {
				issueTypeRequisite = issueType;
				break;
			}
		}
		return issueTypeRequisite;
	}

	/**
	 *
	 * @param browseContext
	 * @param issueTypeId
	 *           Id of the issue type to list
	 * @return a {@link SearchResults} with a list of issues of the specified
	 *         type.
	 */
	protected SearchResults getIssues(BrowseContext browseContext, String issueTypeId) {
		log.debug("Se intenta recuperar los requisitos.");
		JqlClauseBuilder clauseBuilder = JqlQueryBuilder.newClauseBuilder();
		clauseBuilder.project(browseContext.getProject().getId()).and().issueType(issueTypeId);
		Query query = clauseBuilder.buildQuery();
		SearchResults results = null;
		try {
			results = searchProvider.search(query, browseContext.getUser(), new PagerFilter<Issue>(10));
		} catch (SearchException e) {
			e.printStackTrace();
		}
		log.debug((new StringBuilder("Requisitos: ")).append(results.getIssues()).toString());
		return results;
	}

}
